/*
 * Copyright (C) 2009 2DAI
 *
 * Este programa es Software Libre; usted puede redistribuirlo
 * y/o modificarlo bajo los términos de la "GNU General Public
 * License" como lo publica la "FSF Free Software Foundation",
 * o (a su elección) de cualquier versión posterior.
 *
 * Este programa es distribuido con la esperanza de que le será
 * útil, pero SIN NINGUNA GARANTIA; incluso sin la garantía
 * implícita por el MERCADEO o EJERCICIO DE ALGUN PROPOSITO en
 * particular. Vea la "GNU General Public License" para más
 * detalles.
 *
 * Usted debe haber recibido una copia de la "GNU General Public
 * License" junto con este programa, si no, escriba a la "FSF
 * Free Software Foundation, Inc.", 59 Temple Place - Suite 330,
 * Boston, MA  02111-1307, USA.
 */
package data;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import util.Errors;
import util.Sql;

/**
 *
 * Author: Jorge Garrido Oval
 * 
 * Clase de la que implementar para utilizar los datos de la BD
 * Los métodos genéricos ya están implementados, solo hay que implementar los
 * que tienen una estructura sql diferente para cada tabla.
 */
public abstract class DataManager<T> {

    //Atributos
    protected Sql sql;
    private ArrayList<T> list;
    public int index = 0;
    private String tabla = "default";

    //Costructores
    public DataManager() {
        list = new ArrayList();
        sql = new Sql();
    }

    public DataManager(String tabla) {
        list = new ArrayList();
        sql = new Sql();
        this.tabla = tabla;
        requerir();
    }

    //Métodos de desplazamiento por ArrayList
    public T siguiente() {
        if (index < (getList().size() - 1)) {
            return getList().get(++index);
        } else {
            return ultimo();
        }
    }

    public T anterior() {
        if (index > 0) {
            return getList().get(--index);
        } else {
            return primero();
        }
    }

    public T primero() {
        return getList().get(0);
    }

    public T ultimo() {
        return getList().get(getList().size()-1);
    }

    /**
     * Devolverá true si se encuentra en la tabla un regitro similar
     * es por tanto un buscador para no repetir registros.
     * @param param1
     * @param param2
     * @return
     */
    public boolean buscar(String param1, String param2) {
        sql.conectar();
        ResultSet rs = (ResultSet) sql.ejecutarSelect("SELECT * FROM " + tabla +
                " WHERE campo1=" + param1 + " AND campo2=" + param2);
        sql.desconectar();
        if (rs != null) {
            return true;
        } else {
            return false;
        }
    }

    //Métodos abstractos
    /**
     * método para obtener el Resulset(Select) y rellenar el ArrayList
     */
    public abstract void requerir();

    /**
     * método para actualizar el objeto en la BD mediante update
     * @param o
     */
    public abstract void guardar(T o);

    /**
     * método para insertar el objeto en la BD mediante insert
     * @param o
     */
    public abstract void insertar(T o);

    /**
     * método para eliminar el objeto de la BD mediante delete
     * @param o
     */
    public abstract void eliminar(T o);

    /**
     * método para crear una nueva tabla con create table
     * @param tabla
     */
    public abstract void crear(String tabla);

    //Otros métodos
    /**
     * Elimina la tabla de la base de datos
     * @param tabla
     */
    public void drop(String tabla) {
        sql.conectar();
        sql.ejectarUpdate("DROP TABLE " + tabla);
        sql.desconectar();
    }

    /**
     * Recupera el listado de tablas que contiene la BD
     * @return
     */
    public ArrayList listaTablas() {
        ArrayList<String> tablas;
        try {
            sql.conectar();
            ResultSet rs = sql.listarTablas();
            tablas = new ArrayList<String>();
            while (rs.next()) {
                tablas.add(rs.getString("TABLE_NAME"));
            }
            sql.desconectar();
        } catch (SQLException ex) {
            Errors.creaError("ERROR: No se han podido conseguir los datos\n" + ex.getMessage(), ex.getStackTrace());
            return null;
        } finally {
            sql.desconectar();
        }
        return tablas;
    }

    /**
     * Getter del ArrayList
     * @return the list
     */
    public ArrayList<T> getList() {
        return list;
    }

    /**
     * @param tabla the tabla to set
     */
    public void setTabla(String tabla) {
        this.tabla = tabla;
    }
}
